﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using ViewMaker.Core.Utils;
using System.ComponentModel;
using System.Xml.Serialization;

namespace ViewMaker.Core.Controls
{
    /// <summary>
    /// ヘッダーViewコントロール
    /// </summary>
    public abstract class HeaderViewControl : ControlViewControl, IHeaderPropProvider
    {
        /// <summary>
        /// プロパティ定数
        /// </summary>
        public new class Properties : ControlViewControl.Properties
        {
            public const string HeaderPosition = "HeaderPosition";
            public const string HeaderHeight = "HeaderHeight";
            public const string HeaderWidth = "HeaderWidth";
            public const string HeaderHorizontalContentAlignment = "HeaderHorizontalContentAlignment";
            public const string HeaderVerticalAlignment = "HeaderVerticalAlignment";
            public const string HeaderFontSize = "HeaderFontSize";
            public const string HeaderForeground = "HeaderForeground";
            public const string HeaderBackground = "HeaderBackground";
        }

        /// <summary>
        /// ヘッダー位置
        /// </summary>
        [Display(Name = "Header Position", GroupName = LayoutGroup)]
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "HeaderPositionList")]
        public LayoutHeaderPosition HeaderPosition { get; set; }

        /// <summary>
        /// ヘッダー幅
        /// </summary>
        [Display(Name = "Header Width", GroupName = LayoutGroup)]
        public int? HeaderWidth { get; set; }

        /// <summary>
        /// ヘッダー高さ
        /// </summary>
        [Display(Name = "Header Height", GroupName = LayoutGroup)]
        public int? HeaderHeight { get; set; }

        /// <summary>
        /// ヘッダーの水平配置位置
        /// </summary>
        [Display(Name = "Header HAlign", Description = "Header Horizontal Alignment", GroupName = LayoutGroup)]
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "HorizontalAlignmentList")]
        public LayoutHorizontalAlignment? HeaderHorizontalContentAlignment { get; set; }

        /// <summary>
        /// ヘッダーの垂直配置位置
        /// </summary>
        [Display(Name = "Header VAlign", Description = "Header Vertical Alignment", GroupName = LayoutGroup)]
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "VerticalAlignmentList")]
        public LayoutVerticalAlignment? HeaderVerticalAlignment { get; set; }

        /// <summary>
        /// ヘッダーのフォントサイズ
        /// </summary>
        [Display(Name = "Header FontSize", GroupName = StyleGroup)]
        public double? HeaderFontSize { get; set; }

        /// <summary>
        /// ヘッダーの前景色
        /// </summary>
        [Display(Name = "Header Foreground", GroupName = StyleGroup)]
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ColorList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string HeaderForeground { get; set; }

        /// <summary>
        /// ヘッダーの背景色
        /// </summary>
        [Display(Name = "Header Background", GroupName = StyleGroup)]
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ColorList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string HeaderBackground { get; set; }

        [XmlIgnore]
        [Browsable(false)]
        public LayoutHeaderPosition ActualHeaderPosition
        {
            get 
            {
                if (this.HeaderPosition != LayoutHeaderPosition.Default) return this.HeaderPosition;
                if (this.Item.Parent != null && this.Item.Parent.Element is PanelViewControl)
                {
                    return ((PanelViewControl)this.Item.Parent.Element).HeaderPosition;
                }
                return LayoutHeaderPosition.Left;
            }
        }

        [XmlIgnore]
        [Browsable(false)]
        public bool IsComposite 
        { 
            get { return ActualHeaderPosition == LayoutHeaderPosition.Left || ActualHeaderPosition == LayoutHeaderPosition.Top; } 
        }

        #region ShouldSerialize

        public virtual bool ShouldSerializeHeaderWidth() { return HeaderWidth.HasValue; }
        public virtual bool ShouldSerializeHeaderHorizontalContentAlignment() { return HeaderHorizontalContentAlignment.HasValue; }
        public virtual bool ShouldSerializeHeaderVerticalAlignment() { return true; }
        public virtual bool ShouldSerializeHeaderFontSize() { return HeaderFontSize.HasValue; }

        #endregion


        public HeaderViewControl()
        {
            HeaderVerticalAlignment = LayoutVerticalAlignment.Center;
            ColumnSpan = 1;

        }
        public override List<XamlNode> CreateXaml(XamlNode parent)
        {
            var list = new List<XamlNode>();
            if (ActualHeaderPosition != LayoutHeaderPosition.Hidden)
            {
#if !SILVERLIGHT
                var lbl = parent.CreateElement("Label");
#else
                var lbl = parent.CreateElement("sdk", "http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk", "Label");
#endif
                lbl.InnerText = Item.Caption;

                if (!string.IsNullOrEmpty(IsVisibile)) SetBindingAttribute(lbl, "Visibility", IsVisibile + ", Converter={StaticResource BooleanToVisibilityConverter}", true);
#if SILVERLIGHT
                if (!string.IsNullOrEmpty(Item.Name) && !string.IsNullOrEmpty(Item.Caption)) lbl.SetAttribute("Target", "{Binding ElementName=" + Item.Name +"}");                
#endif
                var width = GetHeaderWidth(this);
                if (width.HasValue) lbl.SetAttribute("Width", width.ToString());

                var height = GetHeaderHeight(this);
                if (height.HasValue) lbl.SetAttribute("Height", height.ToString());

                var align = GetHeaderHorizontalContentAlignment(this);
                if (align.HasValue) lbl.SetAttribute("HorizontalContentAlignment", align.ToString());

                var fontSize = GetHeaderFontSize(this);
                if (fontSize.HasValue) lbl.SetAttribute("FontSize", fontSize.ToString());

                var fore = GetHeaderForeground(this);
                if (!string.IsNullOrEmpty(fore)) lbl.SetAttribute("Foreground", fore);

                var back = GetHeaderBackground(this);
                if (!string.IsNullOrEmpty(back)) lbl.SetAttribute("Background", back);

                list.Add(lbl);
            }
            return list;
        }


        internal override void CopyFrom(ViewElement source)
        {
            base.CopyFrom(source);
            var header = source as HeaderViewControl;
            if (header != null)
            {
                this.HeaderPosition = header.HeaderPosition;
                if (header.HeaderWidth.HasValue) this.HeaderWidth = header.HeaderWidth;
                if (header.HeaderHorizontalContentAlignment.HasValue) this.HeaderHorizontalContentAlignment = header.HeaderHorizontalContentAlignment;
                if (header.HeaderVerticalAlignment.HasValue) this.HeaderVerticalAlignment = header.HeaderVerticalAlignment;
                this.HeaderFontSize = header.HeaderFontSize;
                this.HeaderForeground = header.HeaderForeground;
                this.HeaderBackground = header.HeaderBackground;
            }
        }


        #region IHeaderPropProvider メンバー

        public virtual LayoutHorizontalAlignment? GetHeaderHorizontalContentAlignment(ViewControl ctrl)
        {
            if (HeaderHorizontalContentAlignment.HasValue) return HeaderHorizontalContentAlignment;
            if (this.Item.Parent != null)
            {
                var header = this.Item.Parent.Element as IHeaderPropProvider;
                if (header != null) return header.GetHeaderHorizontalContentAlignment(ctrl);
            }
            return null;
        }

        public virtual LayoutVerticalAlignment? GetHeaderVerticalAlignment(ViewControl ctrl)
        {
            if (HeaderVerticalAlignment.HasValue) return HeaderVerticalAlignment;
            if (this.Item.Parent != null)
            {
                var header = this.Item.Parent.Element as IHeaderPropProvider;
                if (header != null) return header.GetHeaderVerticalAlignment(ctrl);
            }
            return null;
        }

        public virtual int? GetHeaderWidth(ViewControl ctrl)
        {
            if (HeaderWidth.HasValue) return HeaderWidth;
            if (this.Item.Parent != null)
            {
                var header = this.Item.Parent.Element as IHeaderPropProvider;
                if (header != null) return header.GetHeaderWidth(ctrl);
            }
            return null;
        }

        public virtual int? GetHeaderHeight(ViewControl ctrl)
        {
            if (HeaderHeight.HasValue) return HeaderHeight;
            if (this.Item.Parent != null)
            {
                var header = this.Item.Parent.Element as IHeaderPropProvider;
                if (header != null) return header.GetHeaderHeight(ctrl);
            }
            return null;
        }

        public virtual double? GetHeaderFontSize(ViewControl ctrl)
        {
            if (HeaderFontSize.HasValue) return HeaderFontSize;
            if (this.Item.Parent != null)
            {
                var header = this.Item.Parent.Element as IHeaderPropProvider;
                if (header != null) return header.GetHeaderFontSize(ctrl);
            }
            return null;
        }

        public virtual string GetHeaderForeground(ViewControl ctrl)
        {
            if (!string.IsNullOrEmpty(HeaderForeground)) return HeaderForeground;
            if (this.Item.Parent != null)
            {
                var header = this.Item.Parent.Element as IHeaderPropProvider;
                if (header != null) return header.GetHeaderForeground(ctrl);
            }
            return null;
        }

        public virtual string GetHeaderBackground(ViewControl ctrl)
        {
            if (!string.IsNullOrEmpty(HeaderBackground)) return HeaderBackground;
            if (this.Item.Parent != null)
            {
                var header = this.Item.Parent.Element as IHeaderPropProvider;
                if (header != null) return header.GetHeaderBackground(ctrl);
            }
            return null;
        }

        #endregion
    }

}
